
package pATT.bNEdit.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Enumeration;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import pATT.bNEdit.base.Nodo;
import pATT.bNEdit.base.Potencial;
import pATT.bNEdit.base.RedBayes;


/**
 * <p>Title: BNEdit</p>
 * <p>Description: Bayesian Network Editor</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Martin Blech
 * @version 1.0
 */

public class NodePropertiesPanel extends JPanel implements Actualizable{
  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
private RedBayes bayesianNetwork = null;
  private String nodeName = null;
  private BNEditInternalFrame internalFrame = null;

  JLabel jLabel1 = new JLabel();
  FlowLayout flowLayout1 = new FlowLayout();
  JTextField textVarName = new JTextField();
  JTable tablePotential = new JTable();
  JScrollPane jScrollPane1 = new JScrollPane();
  JButton buttonAddState = new JButton();
  JButton buttonDeleteState = new JButton();
  JButton buttonNormalize = new JButton();
  JLabel jLabel2 = new JLabel();
  JLabel labelParents = new JLabel();

  public NodePropertiesPanel() {
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
    Component[] components = this.getComponents();
    for (int i = 0; i < components.length; i++) {
      components[i].setEnabled(false);
    }
  }

  void jbInit() throws Exception {
    jLabel1.setText("Variable name:");
    this.setLayout(flowLayout1);
    textVarName.setPreferredSize(new Dimension(100, 19));
    textVarName.setText("");
    textVarName.addKeyListener(new NodePropertiesPanel_textVarName_keyAdapter(this));
    tablePotential.setAutoscrolls(true);
    tablePotential.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    buttonAddState.setToolTipText("Add state");
    buttonAddState.setIcon(ResourceManager.getIcon("plus.gif"));
    buttonAddState.addActionListener(new NodePropertiesPanel_buttonAddState_actionAdapter(this));
    buttonDeleteState.setToolTipText("Delete state");
    buttonDeleteState.setIcon(ResourceManager.getIcon("minus.gif"));
    buttonDeleteState.addActionListener(new NodePropertiesPanel_buttonDeleteState_actionAdapter(this));
    jScrollPane1.setBorder(BorderFactory.createLineBorder(Color.black));
    jScrollPane1.setPreferredSize(new Dimension(230, 100));
    this.setPreferredSize(new Dimension(230, 400));
    buttonNormalize.setToolTipText("Normalize distribution");
    buttonNormalize.setIcon(ResourceManager.getIcon("hideGraph.gif"));
    buttonNormalize.addActionListener(new NodePropertiesPanel_buttonNormalize_actionAdapter(this));
    jLabel2.setText("Parent node names:");
    this.add(jLabel1, null);
    this.add(textVarName, null);
    this.add(jLabel2, null);
    this.add(labelParents, null);
    this.add(jScrollPane1, null);
    jScrollPane1.getViewport().add(tablePotential, null);
    this.add(buttonAddState, null);
    this.add(buttonDeleteState, null);
    this.add(buttonNormalize, null);


  }

  /**
   * setBayesianNetwork
   *
   * @param bayesianNetwork RedBayes
   */
  public void setBayesianNetwork(RedBayes bayesianNetwork) {
    this.bayesianNetwork = bayesianNetwork;
    setCurrentNode(null);
  }

  /**
   * Sets the currently selected node name
   * @param nodeName String
   */
  public void setCurrentNode(String nodeName) {
    this.nodeName = nodeName;
    Component[] components = this.getComponents();
    if (nodeName==null || bayesianNetwork.getNodo(nodeName)==null) {
      labelParents.setText("");
      textVarName.setText(null);
      this.setEnabled(false);
      for (int i = 0; i < components.length; i++) {
        components[i].setEnabled(false);
      }
      tablePotential.setEnabled(false);
    }
    else {
      textVarName.setText(nodeName);
      Nodo node = bayesianNetwork.getNodo(nodeName);
      tablePotential.setModel(new PotencialTableModel(node));
      this.setEnabled(true);
      for (int i = 0; i < components.length; i++) {
        components[i].setEnabled(true);
      }
      tablePotential.setEnabled(true);
      if (node.getEstados().size()<=1)
        buttonDeleteState.setEnabled(false);
      Enumeration parentsEnum =
          bayesianNetwork.getNodo(nodeName).getPadres().elements();
      StringBuffer parentNames = new StringBuffer();
      if (parentsEnum.hasMoreElements()) {
        String parentName =
            bayesianNetwork.NombreExt((Nodo)parentsEnum.nextElement());
        parentNames.append(parentName);
      }
      while (parentsEnum.hasMoreElements()) {
        String parentName =
            bayesianNetwork.NombreExt((Nodo)parentsEnum.nextElement());
        parentNames.append(", ");
        parentNames.append(parentName);
      }
      labelParents.setText(parentNames.toString());

    }
  }

  /**
   * Sets the BNEditInternalFrame
   * @param internalFrame BNEditInternalFrame
   */
  public void setInternalFrame(BNEditInternalFrame internalFrame) {
    this.internalFrame = internalFrame;
  }

  /**
   * When the user presses the ENTER key, the variable name should be updated
   * @param e KeyEvent
   */
  void textVarName_keyTyped(KeyEvent e) {
    if (e.getKeyChar()==KeyEvent.VK_ENTER){
      internalFrame.renameVar(nodeName, textVarName.getText());
    }
  }

  /**
   * Add a state to the node with a default name
   * @param e ActionEvent
   */
  void buttonAddState_actionPerformed(ActionEvent e) {
    Nodo node = bayesianNetwork.getNodo(nodeName);
    Potencial p= node.getProbabilidadOriginal();
    int stateNum = node.getEstados().size() + 1;
    node.addEstado("State " + stateNum);
    this.setCurrentNode(nodeName);
    setOldValues(node.getProbabilidad(), p, p.tamanio());
  }

  private void setOldValues(Potencial actual, Potencial anterior, int limite){
    for (int pos=0;pos<limite;pos++){
      actual.set(pos,anterior.get(pos));
    }

  }

  /**
   * Remove a state from the node
   * @param e ActionEvent
   */
  void buttonDeleteState_actionPerformed(ActionEvent e) {
    Nodo node = bayesianNetwork.getNodo(nodeName);
    int numStates = node.getEstados().size();
    if (numStates>1){
      Potencial p= node.getProbabilidadOriginal();
      node.delEstado( (String) node.getEstados().lastElement());
      setOldValues(node.getProbabilidad(), p, node.getProbabilidad().tamanio());
    }
    this.setCurrentNode(nodeName);
  }

  void buttonNormalize_actionPerformed(ActionEvent e) {
    Nodo node = bayesianNetwork.getNodo(nodeName);
    node.getProbabilidad().normalizar();
    tablePotential.repaint();
  }
}

class NodePropertiesPanel_textVarName_keyAdapter extends java.awt.event.KeyAdapter {
  NodePropertiesPanel adaptee;

  NodePropertiesPanel_textVarName_keyAdapter(NodePropertiesPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void keyTyped(KeyEvent e) {
    adaptee.textVarName_keyTyped(e);
  }
}

class NodePropertiesPanel_buttonAddState_actionAdapter implements java.awt.event.ActionListener {
  NodePropertiesPanel adaptee;

  NodePropertiesPanel_buttonAddState_actionAdapter(NodePropertiesPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.buttonAddState_actionPerformed(e);
  }
}

class NodePropertiesPanel_buttonDeleteState_actionAdapter implements java.awt.event.ActionListener {
  NodePropertiesPanel adaptee;

  NodePropertiesPanel_buttonDeleteState_actionAdapter(NodePropertiesPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.buttonDeleteState_actionPerformed(e);
  }
}

class NodePropertiesPanel_buttonNormalize_actionAdapter implements java.awt.event.ActionListener {
  NodePropertiesPanel adaptee;

  NodePropertiesPanel_buttonNormalize_actionAdapter(NodePropertiesPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.buttonNormalize_actionPerformed(e);
  }
}
